#include "context.h"

static void OCL_CALLBACK ocl_notify(const char *errinfo,
					   const void *private_info, size_t cb,
					   void *user_data)
{
	FILE *fp = user_data ? (FILE *)user_data : stderr;
	fprintf( fp, "%s\n", errinfo );
	(void) private_info;
	(void) cb;
}



int  ocl_context_load(ocl_context        *context, 
					  cl_uint             num_devices,
					  const cl_device_id *devices )
{
	static const char fn[] = "[ocl_context_load]";
	assert( context );
	assert( num_devices > 0 );
	assert( devices != NULL );
	
	memset( context, 0, sizeof(ocl_context) );
	ocl_errno = CL_SUCCESS;
	
	if( ocl_logfile ) fprintf( ocl_logfile, "%s Create Context: %u device(s)@%p\n", fn, (unsigned)num_devices, devices ); 
	context->handle = clCreateContext( NULL, num_devices, devices, ocl_notify, NULL, &ocl_errno);
	
	if( CL_SUCCESS != ocl_errno )
		goto ERROR;
	
	if( ocl_logfile ) fprintf( ocl_logfile, "%s CALLOC(%u,cl_device_id)\n", fn, (unsigned)num_devices);
	
	context->num_devices = num_devices;
	if( NULL == ( context->DEVICES = MDS_CALLOC_AS(cl_device_id,context->num_devices) ) )
	{
		goto ERROR;
	}
	
	if( ocl_logfile ) fprintf( ocl_logfile, "%s Read cl_device_id\n", fn );
	if( CL_SUCCESS != ( ocl_errno = clGetContextInfo(context->handle, CL_CONTEXT_DEVICES, context->num_devices * sizeof(cl_device_id), context->DEVICES, NULL) ) )
	{
		goto ERROR;
	}
	
	
	return 0;
	
ERROR:
	ocl_context_quit( context );
	return -1;
}


void ocl_context_quit( ocl_context *context )
{
	static const char fn[] = "[ocl_context_quit]";
	
	if( context )
	{
		if( ocl_logfile ) fprintf( ocl_logfile, "%s\n", fn );
		if( context->DEVICES )
		{
			assert( context->num_devices > 0 );
			MDS_FREE_AS(cl_device_id, context->DEVICES, context->num_devices );
		}
		
		if( context->handle )    
			clReleaseContext( context->handle );
		
		memset( context, 0, sizeof(ocl_context) );
	}
}
